﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Framework.Infrastructure
{
    public static class MSContextUtility
    {
        public static IQueryable<TEntity> MergeSortExpression<TEntity>(this IQueryable<TEntity> query, Expression<Func<TEntity, dynamic>> sortExpression, bool ascending = true, bool hasSorted = false)
        {
            string orderByCMD = string.Empty;
            if (hasSorted)
            {
                if (!ascending)
                {
                    orderByCMD = "ThenByDescending";
                }
                else
                {
                    orderByCMD = "ThenBy";
                }
            }
            else
            {
                if (!ascending)
                {
                    orderByCMD = "OrderByDescending";
                }
                else
                {
                    orderByCMD = "OrderBy";
                }
            }
            LambdaExpression le = Utility.GetLambdaExpression(typeof(TEntity)
                    , ((sortExpression.Body as UnaryExpression).Operand as MemberExpression).Member.Name);
           

            MethodCallExpression orderByCallExpression =
                    Expression.Call(typeof(Queryable),
                    orderByCMD,
                    new Type[] { typeof(TEntity), le.Body.Type },
                    query.Expression,
                    le);

            return query.Provider.CreateQuery<TEntity>(orderByCallExpression);
        }


        public static IQueryable<TElement> GetQueryable<TEntity, TElement>(this TEntity entity, string collectionName)
            where TEntity : DbEntity
            where TElement : class
        {
            IQueryable<TElement> query = null;
            if (entity.EntityEntry != null)
            {
                query = entity.EntityEntry.Collection(collectionName).Query().Cast<TElement>();
            }
            return query;
        }

        public static IQueryable<TElement> GetQueryable<TEntity, TElement>(this TEntity entity, Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
            where TEntity : DbEntity
            where TElement : class
        {
            IQueryable<TElement> query = null;
            query = entity.EntityEntry.Cast<TEntity>().Collection(navigationProperty).Query().Cast<TElement>();
            return query;
        }

        public static void ReferenceLoad<TEntity, TProperty>(this TEntity entity, Expression<Func<TEntity, TProperty>> navigationProperty)
            where TEntity : DbEntity
            where TProperty : class
        {
            entity.EntityEntry.Cast<TEntity>().Reference(navigationProperty).Load();
        }

        public static void CollectionLoad<TEntity, TElement>(this TEntity entity, Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
            where TEntity : DbEntity
            where TElement : class
        {
            entity.EntityEntry.Cast<TEntity>().Collection(navigationProperty).Load();
        }
    }
}
